namespace C1.Win.C1FlexGrid
{
    using C1.Util;
    using C1.Util.Licensing;
    using C1.Win.C1FlexGrid.Util;
    using C1.Win.C1FlexGrid.Util.BaseControls;
    using C1.Win.C1FlexGrid.Util.Styles;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Windows.Forms;

    public abstract class C1FlexGridBase : C1.Win.C1FlexGrid.Util.BaseControls.ScrollableControl
    {
        internal AllowDraggingEnum _allowDragging;
        internal bool _allowEditing;
        internal AllowFreezingEnum _allowFreezing;
        internal AllowResizingEnum _allowResizing;
        internal AllowSortingEnum _allowSorting;
        internal bool _autoResize;
        private bool _cancelScroll;
        internal bool _control;
        internal DrawModeEnum _drawMode;
        internal GridEditHandler _editHandler;
        internal bool _extendLastCol;
        internal bool _flatStyle;
        internal FocusRectEnum _focusRect;
        internal static List<Bitmap> _glyphs;
        internal static Style _glyphStyle;
        internal GridModel _grid = new GridModel(50, 10, 1, 1);
        internal HighLightEnum _highLight;
        internal GridKbdHandler _kbdHandler;
        private DateTime _lastClick = DateTime.MinValue;
        private ProviderInfo _licProvider;
        internal GridMouseHandler _mouseHandler;
        internal Column _mouseSortCol;
        private static Point[] _ptCursor = new Point[3];
        private bool _refreshing;
        internal bool _shift;
        internal ShowButtonsEnum _showButtons;
        internal bool _showCursor;
        internal bool _showSort;
        internal static StyleContext _staticStyles;
        internal bool _validating;
        internal CellRange _viewRange;

        public event RowColEventHandler AfterCollapse;

        public event ListChangedEventHandler AfterDataRefresh;

        public event DragRowColEventHandler AfterDragColumn;

        public event DragRowColEventHandler AfterDragRow;

        public event RowColEventHandler AfterEdit;

        public event RowColEventHandler AfterFreezeColumn;

        public event RowColEventHandler AfterFreezeRow;

        public event RowColEventHandler AfterResizeColumn;

        public event RowColEventHandler AfterResizeRow;

        public event RangeEventHandler AfterRowColChange;

        public event RangeEventHandler AfterScroll;

        public event RangeEventHandler AfterSelChange;

        public event SortColEventHandler AfterSort;

        public event RowColEventHandler BeforeAutosizeColumn;

        public event RowColEventHandler BeforeAutosizeRow;

        public event RowColEventHandler BeforeCollapse;

        public event DragRowColEventHandler BeforeDragColumn;

        public event DragRowColEventHandler BeforeDragRow;

        public event RowColEventHandler BeforeEdit;

        public event RowColEventHandler BeforeFreezeColumn;

        public event RowColEventHandler BeforeFreezeRow;

        public event BeforeMouseDownEventHandler BeforeMouseDown;

        public event RowColEventHandler BeforeResizeColumn;

        public event RowColEventHandler BeforeResizeRow;

        public event RangeEventHandler BeforeRowColChange;

        public event RangeEventHandler BeforeScroll;

        public event RowColEventHandler BeforeScrollTip;

        public event RangeEventHandler BeforeSelChange;

        public event SortColEventHandler BeforeSort;

        public event RowColEventHandler CellButtonClick;

        public event RowColEventHandler CellChanged;

        public event EventHandler ChangeEdit;

        public event RowColEventHandler ComboCloseUp;

        public event RowColEventHandler ComboDropDown;

        public event EventHandler EnterCell;

        public event GridChangedEventHandler GridChanged;

        public event GridErrorEventHandler GridError;

        public event KeyEditEventHandler KeyDownEdit;

        public event KeyPressEditEventHandler KeyPressEdit;

        public event KeyEditEventHandler KeyUpEdit;

        public event EventHandler LeaveCell;

        public event OwnerDrawCellEventHandler OwnerDrawCell;

        public event EventHandler RowColChange;

        public event EventHandler SelChange;

        public event RowColEventHandler SetupEditor;

        public event RowColEventHandler StartEdit;

        public event ValidateEditEventHandler ValidateEdit;

        static C1FlexGridBase()
        {
            string[] strArray = new string[] { "Ascending", "Descending", "Checked", "Unchecked", "Grayed", "Collapsed", "Expanded" };
            _glyphs = new List<Bitmap>();
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            foreach (string str in strArray)
            {
                foreach (string str2 in executingAssembly.GetManifestResourceNames())
                {
                    if (str2.EndsWith(str + ".bmp"))
                    {
                        _glyphs.Add(new Bitmap(executingAssembly.GetManifestResourceStream(str2)));
                        break;
                    }
                }
            }
            _staticStyles = new StyleContext();
            _staticStyles.TransparentColor = Color.Red;
            Style style = _staticStyles.AddStyle("Button");
            style.SetAttribute("AlignHorz", AlignHorzEnum.Center);
            style.SetAttribute("AlignVert", AlignVertEnum.Center);
            style.SetAttribute("Wrap", false);
            style.SetAttribute("Trimming", StringTrimming.None);
            style.SetAttribute("AlignImage", AlignImageEnum.CenterCenter);
            style.SetAttribute("Opaque", false);
            _glyphStyle = style;
        }

        public C1FlexGridBase()
        {
            this._grid._designMode = true;
            this._mouseHandler = new GridMouseHandler(this);
            this._kbdHandler = new GridKbdHandler(this);
            this._editHandler = new GridEditHandler(this);
            this._grid.OnGridChanged += new GridChangedEventHandler(this.OnGridChanged);
            this.Styles.Normal.Font = this.Font;
            base.BackColor = this.Styles.Normal.BackColor;
            this.OnFontChanged();
            this.AllowEditing = true;
            this.AllowSorting = AllowSortingEnum.SingleColumn;
            this.AllowResizing = AllowResizingEnum.Columns;
            this.AllowDragging = AllowDraggingEnum.Columns;
            this.AutoResize = true;
            this.HighLight = HighLightEnum.Always;
            this.FocusRect = FocusRectEnum.Light;
            this.DrawMode = DrawModeEnum.Normal;
            this.ShowButtons = ShowButtonsEnum.WithFocus;
            this.ShowCursor = false;
            this.ShowSort = true;
            this._flatStyle = true;
            this._mouseSortCol = null;
            this._licProvider = new ProviderInfo(typeof(C1FlexGridBase), this);
        }

        public void AddItem(object[] items)
        {
            this.AddItem(items, this.Rows.Count, 0);
        }

        public void AddItem(string item)
        {
            this.AddItem(item, this.Rows.Count);
        }

        public void AddItem(string item, int index)
        {
            this.Rows.Insert(index);
            if (item != null)
            {
                string[] strArray = item.Split(new char[] { this.ClipSeparators[0] });
                int num = Math.Min(strArray.Length, this.Cols.Count);
                for (int i = 0; i < num; i++)
                {
                    this.SetData(index, i, strArray[i], true);
                }
            }
        }

        public void AddItem(object[] items, int rowIndex, int colIndex)
        {
            this.Rows.Insert(rowIndex);
            for (int i = 0; i < items.Length; i++)
            {
                int col = colIndex + i;
                if (col >= this.Cols.Count)
                {
                    return;
                }
                this.SetData(rowIndex, col, items[i], true);
            }
        }

        public double Aggregate(AggregateEnum function)
        {
            return this.Aggregate(function, AggregateFlags.None);
        }

        public double Aggregate(AggregateEnum function, AggregateFlags flags)
        {
            CellRange selection = this.Selection;
            if (this.SelectionMode == SelectionModeEnum.ListBox)
            {
                selection.r1 = selection.r2 = -1;
            }
            return this.Aggregate(function, selection, flags);
        }

        public double Aggregate(AggregateEnum function, CellRange rg)
        {
            return this.Aggregate(function, rg, AggregateFlags.None);
        }

        public double Aggregate(AggregateEnum function, CellRange rg, AggregateFlags flags)
        {
            return this._grid.Aggregate(function, rg, flags);
        }

        public double Aggregate(AggregateEnum function, int r1, int c1, int r2, int c2)
        {
            return this.Aggregate(function, r1, c1, r2, c2, AggregateFlags.None);
        }

        public double Aggregate(AggregateEnum function, int r1, int c1, int r2, int c2, AggregateFlags flags)
        {
            CellRange rg = new CellRange(this._grid, r1, c1, r2, c2);
            return this.Aggregate(function, rg, flags);
        }

        public virtual void AutoSizeCol(int col)
        {
            this.AutoSizeCol(col, 4);
        }

        public virtual void AutoSizeCol(int col, int extraSpace)
        {
            this.AutoSizeCols(0, col, this.Rows.Count - 1, col, extraSpace, AutoSizeFlags.IgnoreHidden);
        }

        public virtual void AutoSizeCols()
        {
            this.AutoSizeCols(4);
        }

        public virtual void AutoSizeCols(int extraSpace)
        {
            this.AutoSizeCols(0, 0, this.Rows.Count - 1, this.Cols.Count - 1, extraSpace, AutoSizeFlags.IgnoreHidden);
        }

        public virtual void AutoSizeCols(int col1, int col2, int extraSpace)
        {
            this.AutoSizeCols(0, col1, this.Rows.Count - 1, col2, extraSpace, AutoSizeFlags.IgnoreHidden);
        }

        public virtual void AutoSizeCols(int row1, int col1, int row2, int col2, int extraSpace, AutoSizeFlags flags)
        {
            bool redraw = this.Redraw;
            if (col1 != col2)
            {
                this.Redraw = false;
            }
            try
            {
                using (Graphics graphics = base.CreateGraphics())
                {
                    this.AutoSizeCols(graphics, row1, col1, row2, col2, extraSpace, flags);
                }
            }
            finally
            {
                this.Redraw = redraw;
            }
        }

        internal virtual void AutoSizeCols(Graphics g, int row1, int col1, int row2, int col2, int extra, AutoSizeFlags flags)
        {
            int num3;
            if (row2 > (this.Rows.Count - 1))
            {
                row2 = this.Rows.Count - 1;
            }
            if (col2 > (this.Cols.Count - 1))
            {
                col2 = this.Cols.Count - 1;
            }
            bool flag = (flags & AutoSizeFlags.IgnoreHidden) != AutoSizeFlags.None;
            bool flag2 = (flags & AutoSizeFlags.SameSize) != AutoSizeFlags.None;
            int num = -1;
            for (num3 = col1; num3 <= col2; num3++)
            {
                if (!flag || (this.Cols[num3].WidthDisplay != 0))
                {
                    int num4 = this._grid._tree.TreeWidth(num3);
                    for (int i = row1; i <= row2; i++)
                    {
                        if (!flag || (this.Rows[i].HeightDisplay != 0))
                        {
                            Image image;
                            CheckEnum enum2;
                            string str = this.GetDataDisplay(i, num3, out image, out enum2);
                            if ((image != null) || (str.Length != 0))
                            {
                                int num5 = this.GetStyleDisplay(i, num3).GetWidth(g, str, image) + num4;
                                if (num5 > num)
                                {
                                    num = num5;
                                }
                            }
                        }
                    }
                    if (!flag2 && (num > -1))
                    {
                        this.Cols[num3].Width = num + extra;
                        num = -1;
                    }
                }
            }
            if (flag2 && (num > -1))
            {
                for (num3 = col1; num3 <= col2; num3++)
                {
                    this.Cols[num3].Width = num + extra;
                }
            }
        }

        public virtual void AutoSizeRow(int row)
        {
            this.AutoSizeRows(row, 0, row, this.Cols.Count - 1, 0, AutoSizeFlags.IgnoreHidden);
        }

        public virtual void AutoSizeRows()
        {
            this.AutoSizeRows(0, 0, this.Rows.Count - 1, this.Cols.Count - 1, 0, AutoSizeFlags.IgnoreHidden);
        }

        public virtual void AutoSizeRows(int row1, int col1, int row2, int col2, int extra, AutoSizeFlags flags)
        {
            using (Graphics graphics = base.CreateGraphics())
            {
                this.AutoSizeRows(graphics, row1, col1, row2, col2, extra, flags);
            }
        }

        internal virtual void AutoSizeRows(Graphics g, int row1, int col1, int row2, int col2, int extra, AutoSizeFlags flags)
        {
            int num2;
            if (row2 > (this.Rows.Count - 1))
            {
                row2 = this.Rows.Count - 1;
            }
            if (col2 > (this.Cols.Count - 1))
            {
                col2 = this.Cols.Count - 1;
            }
            bool flag = (flags & AutoSizeFlags.IgnoreHidden) != AutoSizeFlags.None;
            bool flag2 = (flags & AutoSizeFlags.SameSize) != AutoSizeFlags.None;
            int num = -1;
            for (num2 = row1; num2 <= row2; num2++)
            {
                for (int i = col1; i <= col2; i++)
                {
                    if (!flag || (this.Cols[i].WidthDisplay != 0))
                    {
                        Image image;
                        CheckEnum enum2;
                        string str = this.GetDataDisplay(num2, i, out image, out enum2);
                        if ((image != null) || ((str != null) && (str.Length != 0)))
                        {
                            int num4 = this.GetStyleDisplay(num2, i).GetHeight(g, this.Cols[i].WidthDisplay, str, image);
                            if (num4 > num)
                            {
                                num = num4;
                            }
                        }
                    }
                }
                if (!flag2 && (num > -1))
                {
                    int num5 = num + extra;
                    if (num5 <= this.Rows.DefaultSize)
                    {
                        num5 = -1;
                    }
                    this.Rows[num2].Height = num5;
                    num = -1;
                }
            }
            if (flag2 && (num > -1))
            {
                int num6 = num + extra;
                if (num6 <= this.Rows.DefaultSize)
                {
                    num6 = -1;
                }
                for (num2 = row1; num2 <= row2; num2++)
                {
                    this.Rows[num2].Height = num6;
                }
            }
        }

        internal bool CanStartEdit(int row, int col)
        {
            if (!this.AllowEditing || this._grid.IsBadRowCol(row, col))
            {
                return false;
            }
            if (!this.Cols[col].AllowEditing || !this.Rows[row].AllowEditing)
            {
                return false;
            }
            if (this.BeforeEdit != null)
            {
                RowColEventArgs e = new RowColEventArgs(row, col);
                this.BeforeEdit(this, e);
                if (e.Cancel)
                {
                    return false;
                }
            }
            return true;
        }

        internal bool CellHasButton(int row, int col)
        {
            bool flag = this.IsCellCursor(row, col);
            bool flag2 = this.Editor is TextBox;
            if ((!flag || (this.Editor == null)) || flag2)
            {
                switch (this._showButtons)
                {
                    case ShowButtonsEnum.WhenEditing:
                        if (!flag)
                        {
                            return false;
                        }
                        return flag2;

                    case ShowButtonsEnum.WithFocus:
                        return flag;

                    case ShowButtonsEnum.Always:
                        return true;
                }
            }
            return false;
        }

        internal bool CellHasEditor(int row, int col)
        {
            if ((!this.AllowEditing || !this.Cols[col].AllowEditing) || !this.Rows[row].AllowEditing)
            {
                return false;
            }
            if (this._grid.IsCellFixed(row, col))
            {
                return false;
            }
            if (this.BeforeEdit == null)
            {
                return true;
            }
            RowColEventArgs e = new RowColEventArgs(row, col);
            this.BeforeEdit(this, e);
            return !e.Cancel;
        }

        internal virtual int CheckNodeChildren(int row, int col, int level)
        {
            return this._grid.CheckNodeChildren(row, level);
        }

        public void Clear()
        {
            this.Clear(ClearFlags.All);
        }

        public void Clear(ClearFlags clear)
        {
            this.Clear(clear, new CellRange(this._grid, 0, 0, this.Rows.Count - 1, this.Cols.Count - 1));
        }

        public void Clear(ClearFlags clear, CellRange rg)
        {
            this._grid.Clear(clear, rg);
        }

        public void Clear(ClearFlags clear, int row, int col)
        {
            this.Clear(clear, new CellRange(this._grid, row, col, row, col));
        }

        public void Clear(ClearFlags clear, int row1, int col1, int row2, int col2)
        {
            this.Clear(clear, new CellRange(this._grid, row1, col1, row2, col2));
        }

        protected virtual int DrawCell(PaintEventArgs e, int row, int col)
        {
            Rectangle cellRectDisplay = this.GetCellRectDisplay(row, col);
            if (((cellRectDisplay.Left <= base.ClientRectangle.Right) && !cellRectDisplay.IsEmpty) && cellRectDisplay.IntersectsWith(e.ClipRectangle))
            {
                Image image;
                CheckEnum enum2;
                string str = this.GetDataDisplay(row, col, out image, out enum2);
                Style styleDisplay = this.GetStyleDisplay(row, col);
                this.DrawCell(e.Graphics, row, col, styleDisplay, cellRectDisplay, str, image, enum2);
            }
            return col;
        }

        internal virtual void DrawCell(Graphics g, int row, int col, Style s, Rectangle rc, string str, Image img, CheckEnum chk)
        {
            bool flag = this.IsCellCursor(row, col);
            if (this.CellHasButton(row, col) && this.CellHasEditor(row, col))
            {
                Rectangle buttonRect;
                EditorTypeEnum editorType = this.EditHandler.GetEditorType(row, col);
                ButtonState state = this._flatStyle ? ButtonState.Flat : ButtonState.Normal;
                switch (editorType)
                {
                    case EditorTypeEnum.DropDown:
                        if (!flag || (this.Editor == null))
                        {
                            buttonRect = this.EditHandler.GetButtonRect(rc);
                            if (buttonRect.Width > 0)
                            {
                                ControlPaint.DrawComboButton(g, buttonRect, state);
                            }
                            rc.Width -= buttonRect.Width - 1;
                        }
                        else
                        {
                            str = null;
                            img = null;
                        }
                        break;

                    case EditorTypeEnum.PopUp:
                    case EditorTypeEnum.PopEdit:
                        buttonRect = this.EditHandler.GetButtonRect(rc);
                        if (buttonRect.Width > 0)
                        {
                            ControlPaint.DrawButton(g, buttonRect, state);
                            if (this.CellButtonImage == null)
                            {
                                _glyphStyle.Render(g, buttonRect, "...");
                            }
                            else
                            {
                                _glyphStyle.Render(g, buttonRect, this.CellButtonImage);
                            }
                        }
                        rc.Width -= buttonRect.Width - 1;
                        break;
                }
            }
            Image checkImage = this.GetCheckImage(chk);
            if (checkImage != null)
            {
                img = checkImage;
                if (this._grid.ShowValueAsCheck(row, col))
                {
                    str = null;
                }
            }
            this.DrawCellBody(g, row, col, s, rc, str, img);
            if ((this.Rows.Frozen > 0) && (row == ((this.Rows.Fixed + this.Rows.Frozen) - 1)))
            {
                g.FillRectangle(SystemBrushes.ControlDark, rc.X, rc.Bottom - 1, rc.Width + 1, 1);
            }
            if ((this.Cols.Frozen > 0) && (col == ((this.Cols.Fixed + this.Cols.Frozen) - 1)))
            {
                g.FillRectangle(SystemBrushes.ControlDark, rc.Right - 1, rc.Y, 1, rc.Height);
            }
            if ((flag && (this._focusRect != FocusRectEnum.None)) && (this.Focused && !this.IsCellFixed(row, col)))
            {
                rc = s.GetContentRectangle(rc);
                int cellIndent = this._grid._tree.GetCellIndent(row, col);
                if ((cellIndent > 0) && (rc.Width > 12))
                {
                    rc = s.GetTextRectangle(rc, img);
                    rc.X += cellIndent;
                    rc.Width -= cellIndent;
                }
                switch (this._focusRect)
                {
                    case FocusRectEnum.Light:
                        ControlPaint.DrawFocusRectangle(g, rc);
                        return;

                    case FocusRectEnum.Heavy:
                        ControlPaint.DrawFocusRectangle(g, rc);
                        rc.Inflate(-1, -1);
                        ControlPaint.DrawFocusRectangle(g, rc);
                        return;

                    case FocusRectEnum.Solid:
                    {
                        rc.Width--;
                        rc.Height--;
                        Pen pen = new Pen(this.Styles.Highlight.BackColor);
                        g.DrawRectangle(pen, rc);
                        pen.Dispose();
                        return;
                    }
                    case FocusRectEnum.Raised:
                        Win32.DrawBorder3D(g, rc, Border3DStyle.RaisedOuter);
                        return;

                    case FocusRectEnum.Inset:
                        Win32.DrawBorder3D(g, rc, Border3DStyle.SunkenInner);
                        return;

                    default:
                        return;
                }
            }
        }

        internal virtual void DrawCellBase(Graphics g, int row, int col, Style s, Rectangle rc, string str, Image img, DrawCellFlags flags)
        {
            int num = this._grid._tree.TreeWidth(col);
            if (((row == 0) && (this.Rows.Fixed > 0)) && ((num > 0) && this._grid._tree.IsFlagSet(TreeStyleFlags.ButtonBar)))
            {
                this._grid._tree.DrawButtonBar(g, s, rc, str, img);
            }
            else
            {
                if (((this._showSort && (row == 0)) && ((this.Rows.Fixed > 0) && (this.Cols[col] == this._grid._mouseSortCol))) && ((rc.Width > 12) && (rc.Height > 10)))
                {
                    SortFlags sort = this._grid._mouseSortCol.Sort;
                    if ((sort & (SortFlags.Descending | SortFlags.Ascending)) != SortFlags.None)
                    {
                        Bitmap bitmap = ((sort & SortFlags.Ascending) != SortFlags.None) ? _glyphs[0] : _glyphs[1];
                        int num2 = bitmap.Width + 6;
                        Margins attribute = (Margins) s.GetAttribute("Padding");
                        attribute.Right += num2;
                        s.Render(g, rc, str, img, (RenderFlags) flags);
                        attribute.Right -= num2;
                        rc.X = rc.Right - num2;
                        rc.Width = num2;
                        CFGraphics.DrawImage(g, bitmap, rc, Color.Red);
                        return;
                    }
                }
                if (((this._showCursor && (col == 0)) && ((row == this.Row) && (this.Cols.Fixed > 0))) && ((rc.Width > 12) && (rc.Height > 10)))
                {
                    _ptCursor[0].X = _ptCursor[1].X = 5;
                    _ptCursor[2].X = _ptCursor[0].X + 5;
                    _ptCursor[2].Y = (rc.Y + (rc.Height / 2)) - 1;
                    _ptCursor[0].Y = _ptCursor[2].Y + 5;
                    _ptCursor[1].Y = _ptCursor[2].Y - 5;
                    Margins margins2 = (Margins) s.GetAttribute("Padding");
                    margins2.Left += 12;
                    s.Render(g, rc, str, img, (RenderFlags) flags);
                    margins2.Left -= 12;
                    Brush brush = (Brush) s.GetAttribute("ForeColor");
                    g.FillPolygon(brush, _ptCursor);
                }
                else
                {
                    if ((num > 0) && (rc.Width > 12))
                    {
                        Node nd = this.Rows[row].Node;
                        if ((nd != null) && (nd.Level >= 0))
                        {
                            int num3 = (nd.Level + 1) * this._grid._tree.Indent;
                            Margins margins3 = (Margins) s.GetAttribute("Padding");
                            margins3.Left += num3;
                            s.Render(g, rc, str, img, (RenderFlags) flags);
                            margins3.Left -= num3;
                            this._grid._tree.DrawNode(this, g, rc, nd, row);
                            return;
                        }
                    }
                    s.Render(g, rc, str, img, (RenderFlags) flags);
                }
            }
        }

        internal virtual void DrawCellBody(Graphics g, int row, int col, Style s, Rectangle rc, string str, Image img)
        {
            if ((this._drawMode == DrawModeEnum.OwnerDraw) && (this.OwnerDrawCell != null))
            {
                CellStyle style = new CellStyle(s);
                OwnerDrawCellEventArgs e = new OwnerDrawCellEventArgs(this, g, row, col, style, rc, str, img);
                this.OwnerDrawCell(this, e);
                if (e.Handled)
                {
                    return;
                }
                if (e._dirty)
                {
                    e.DrawCell();
                    return;
                }
            }
            this.DrawCellBase(g, row, col, s, rc, str, img, DrawCellFlags.All);
        }

        protected virtual void DrawGrid(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if ((this.Rows.Count == 0) || (this.Cols.Count == 0))
            {
                CellStyle style = this.Styles[CellStyleEnum.EmptyArea];
                g.FillRectangle(style.BackColorBrush, base.ClientRectangle);
            }
            else
            {
                Rectangle rectangle;
                int num = this.Rows.Fixed + this.Rows.Frozen;
                int num2 = Math.Max(num, this.TopRow);
                int num3 = Math.Min(this.BottomRow, this.Rows.Count - 1);
                for (int i = 0; i < num; i++)
                {
                    this.DrawRow(e, i);
                }
                if ((num > 0) && (num < this.Rows.Count))
                {
                    int col = (this.RightCol < 0) ? (num - 1) : this.RightCol;
                    rectangle = this.GetCellRectDisplay(num - 1, col, false, false);
                    rectangle.Width = rectangle.Right;
                    rectangle.Height = rectangle.Bottom;
                    rectangle.Location = Point.Empty;
                    base.ExcludeClip(g, rectangle);
                }
                for (int j = num2; j <= num3; j++)
                {
                    this.DrawRow(e, j);
                }
                Rectangle clientRectangle = base.ClientRectangle;
                rectangle = this.GetCellRectDisplay(this.Rows.Count - 1, this.Cols.Count - 1, false, false);
                if (this._extendLastCol)
                {
                    rectangle.Width = clientRectangle.Width - rectangle.Left;
                }
                if ((rectangle.Right < clientRectangle.Right) || (rectangle.Bottom < clientRectangle.Bottom))
                {
                    CellStyle style2 = this.Styles[CellStyleEnum.EmptyArea];
                    Brush backColorBrush = style2.BackColorBrush;
                    Brush borderBrush = style2.BorderBrush;
                    if (rectangle.Right < clientRectangle.Right)
                    {
                        int width = clientRectangle.Right - rectangle.Right;
                        g.FillRectangle(backColorBrush, rectangle.Right, 0, width, clientRectangle.Height);
                        if (borderBrush != null)
                        {
                            g.FillRectangle(borderBrush, rectangle.Right, 0, 1, rectangle.Bottom + 1);
                        }
                    }
                    if (rectangle.Bottom < clientRectangle.Bottom)
                    {
                        int height = clientRectangle.Bottom - rectangle.Bottom;
                        g.FillRectangle(backColorBrush, 0, rectangle.Bottom, clientRectangle.Width, height);
                        if (borderBrush != null)
                        {
                            g.FillRectangle(borderBrush, 0, rectangle.Bottom, rectangle.Right, 1);
                        }
                    }
                }
            }
        }

        protected virtual void DrawRow(PaintEventArgs e, int row)
        {
            if ((this.Cols.Count != 0) && (this.Rows[row].HeightDisplay != 0))
            {
                Rectangle cellRect = this._grid.GetCellRect(row, 0);
                int num = this.Rows.Fixed + this.Rows.Frozen;
                if (row >= num)
                {
                    cellRect.Y += base.ScrollPosition.Y;
                }
                int num2 = this.Cols.Fixed + this.Cols.Frozen;
                for (int i = 0; i < num2; i++)
                {
                    this.DrawCell(e, row, i);
                }
                if ((num2 > 0) && (num2 < this.Cols.Count))
                {
                    cellRect = this._grid.GetCellRect(row, 0);
                    if (row >= num)
                    {
                        cellRect.Y += base.ScrollPosition.Y;
                    }
                    cellRect.Width = this.Cols[num2].Left;
                    base.ExcludeClip(e.Graphics, cellRect);
                }
                if ((this.LeftCol > -1) && (this.RightCol > -1))
                {
                    for (int j = this.LeftCol; j <= this.RightCol; j++)
                    {
                        this.DrawCell(e, row, j);
                    }
                }
            }
        }

        internal virtual bool ExtendCol(int col)
        {
            return (this._extendLastCol && (col == this.Cols.GetLastVisible()));
        }

        internal void ExtendSelection(Point cell, bool show)
        {
            this.ExtendSelection(cell.Y, cell.X, show);
        }

        internal void ExtendSelection(int row, int col, bool show)
        {
            CellRange range = this.SelHandler.GetRange();
            this.Select(range.r1, range.c1, row, col, show);
        }

        public virtual int FindRow(object objFind, int rowStart, int col, bool wrap)
        {
            return this._grid.FindRow(objFind, rowStart, col, wrap);
        }

        public virtual int FindRow(string strFind, int rowStart, int col, bool caseSensitive, bool fullMatch, bool wrap)
        {
            return this._grid.FindRow(strFind, rowStart, col, caseSensitive, fullMatch, wrap);
        }

        public bool FinishEditing()
        {
            return this.FinishEditing(false);
        }

        public bool FinishEditing(bool cancel)
        {
            return this.EditHandler.FinishEditing(cancel);
        }

        internal int First(RowColCollection coll)
        {
            int @fixed = coll.Fixed;
            while ((@fixed < coll.Count) && (coll[@fixed].SizeDisplay == 0))
            {
                @fixed++;
            }
            return @fixed;
        }

        internal virtual Point GetCellAt(int x, int y)
        {
            return this.GetCellAt(x, y, true);
        }

        internal virtual Point GetCellAt(int x, int y, bool fixedOK)
        {
            Point point = new Point(-1, -1);
            if (fixedOK)
            {
                int num3 = this.Rows.Fixed + this.Rows.Frozen;
                for (int i = 0; i < num3; i++)
                {
                    if (this.Rows[i].Bottom > y)
                    {
                        point.Y = i;
                        break;
                    }
                }
            }
            if (point.Y < 0)
            {
                point.Y = this.Rows.GetItemAt(y - base.ScrollPosition.Y);
            }
            if (fixedOK)
            {
                int num4 = this.Cols.Fixed + this.Cols.Frozen;
                for (int j = 0; j < num4; j++)
                {
                    if (this.Cols[j].Right > x)
                    {
                        point.X = j;
                        break;
                    }
                }
            }
            if (point.X < 0)
            {
                point.X = this.Cols.GetItemAt(x - base.ScrollPosition.X);
            }
            if (((point.X < 0) && this._extendLastCol) && (x > 0))
            {
                point.X = this.Cols.GetLastVisible();
            }
            return point;
        }

        public virtual CheckEnum GetCellCheck(int row, int col)
        {
            return this._grid.GetCellCheck(row, col);
        }

        public Image GetCellImage(int row, int col)
        {
            return this._grid.GetCellImage(row, col);
        }

        public CellRange GetCellRange(int row, int col)
        {
            return new CellRange(this._grid, row, col);
        }

        public CellRange GetCellRange(int row1, int col1, int row2, int col2)
        {
            return new CellRange(this._grid, row1, col1, row2, col2);
        }

        public Rectangle GetCellRect(int row, int col, bool show)
        {
            if (show)
            {
                this.ShowCell(row, col);
            }
            return this.GetCellRectDisplay(row, col, true, true);
        }

        internal virtual Rectangle GetCellRectDisplay(int row, int col)
        {
            return this.GetCellRectDisplay(row, col, false, false);
        }

        internal virtual Rectangle GetCellRectDisplay(int row, int col, bool clip)
        {
            return this.GetCellRectDisplay(row, col, clip, clip);
        }

        internal virtual Rectangle GetCellRectDisplay(int row, int col, bool clipHorz, bool clipVert)
        {
            if ((col >= this.Cols.Count) || (row >= this.Rows.Count))
            {
                return Rectangle.Empty;
            }
            Rectangle clientRectangle = base.ClientRectangle;
            Rectangle rectangle2 = clientRectangle;
            if (col > -1)
            {
                rectangle2.X = this.Cols[col].Left;
                rectangle2.Width = this.Cols[col].WidthDisplay;
            }
            if (row > -1)
            {
                rectangle2.Y = this.Rows[row].Top;
                rectangle2.Height = this.Rows[row].HeightDisplay;
            }
            int num = this.Rows.Fixed + this.Rows.Frozen;
            int num2 = this.Cols.Fixed + this.Cols.Frozen;
            if (row >= num)
            {
                rectangle2.Y += base.ScrollPosition.Y;
            }
            if (col >= num2)
            {
                rectangle2.X += base.ScrollPosition.X;
            }
            if (clipHorz)
            {
                if (col >= num2)
                {
                    int left = this.Cols[num2].Left;
                    if (rectangle2.X < left)
                    {
                        rectangle2.Width -= left - rectangle2.X;
                        rectangle2.X = left;
                        if (rectangle2.Width < 0)
                        {
                            rectangle2.Width = 0;
                        }
                    }
                }
                if (rectangle2.Right > clientRectangle.Right)
                {
                    rectangle2.Width -= (rectangle2.Right - clientRectangle.Right) - 3;
                }
            }
            if (clipVert)
            {
                if (row >= num)
                {
                    int top = this.Rows[num].Top;
                    if (rectangle2.Y < top)
                    {
                        rectangle2.Height -= top - rectangle2.Y;
                        rectangle2.Y = top;
                        if (rectangle2.Height < 0)
                        {
                            rectangle2.Height = 0;
                        }
                    }
                }
                if (rectangle2.Bottom > clientRectangle.Bottom)
                {
                    rectangle2.Height -= (rectangle2.Bottom - clientRectangle.Bottom) - 3;
                }
            }
            if (this._extendLastCol && (rectangle2.Right < clientRectangle.Right))
            {
                int lastVisible = this.Cols.GetLastVisible();
                if (col == lastVisible)
                {
                    rectangle2.Width = clientRectangle.Right - rectangle2.Left;
                }
                if (col > lastVisible)
                {
                    rectangle2.X = clientRectangle.Right + 1;
                }
            }
            return rectangle2;
        }

        internal virtual Rectangle GetCellRectEditor(int row, int col)
        {
            Rectangle rectangle = this.GetCellRectDisplay(row, col, true, true);
            if (!this._grid.IsCellFrozen(row, col))
            {
                rectangle.Intersect(this.ScrollRectangle);
            }
            int cellIndent = this._grid._tree.GetCellIndent(row, col);
            if ((cellIndent > 0) && (rectangle.Width > 12))
            {
                rectangle.X += cellIndent;
                rectangle.Width -= cellIndent;
            }
            return rectangle;
        }

        public CellStyle GetCellStyle(int row, int col)
        {
            Style cellStyle = this._grid.GetCellStyle(row, col);
            if (cellStyle == null)
            {
                return null;
            }
            return new CellStyle(cellStyle);
        }

        public CellStyle GetCellStyleDisplay(int row, int col)
        {
            return new CellStyle(this.GetStyleDisplay(row, col));
        }

        internal Image GetCheckImage(CheckEnum chk)
        {
            GlyphEnum none = GlyphEnum.None;
            switch (chk)
            {
                case CheckEnum.None:
                    return null;

                case CheckEnum.Checked:
                    none = GlyphEnum.Checked;
                    break;

                case CheckEnum.Unchecked:
                    none = GlyphEnum.Unchecked;
                    break;

                case CheckEnum.TSChecked:
                    none = GlyphEnum.Checked;
                    break;

                case CheckEnum.TSUnchecked:
                    none = GlyphEnum.Unchecked;
                    break;

                case CheckEnum.TSGrayed:
                    none = GlyphEnum.Grayed;
                    break;
            }
            return _glyphs[(int) none];
        }

        internal Rectangle GetCheckRect(int row, int col, Style s, Rectangle rc)
        {
            int cellIndent = this._grid._tree.GetCellIndent(row, col);
            if ((cellIndent > 0) && (rc.Width > 12))
            {
                rc.X += cellIndent;
                rc.Width -= cellIndent;
            }
            return s.GetImageRectangle(rc, _glyphs[2]);
        }

        public virtual object GetData(int row, int col)
        {
            return this._grid.GetData(row, col);
        }

        public virtual object GetData(int row, string colName)
        {
            return this.GetData(row, this.Cols[colName].Index);
        }

        public virtual string GetDataDisplay(int row, int col)
        {
            return this._grid.GetDataDisplay(row, col);
        }

        public virtual string GetDataDisplay(int row, string colName)
        {
            return this.GetDataDisplay(row, this.Cols[colName].Index);
        }

        internal string GetDataDisplay(int row, int col, out Image img, out CheckEnum chk)
        {
            return this._grid.GetDataDisplay(row, col, out img, out chk);
        }

        internal CheckEnum GetNextCheckValue(CheckEnum chk)
        {
            switch (chk)
            {
                case CheckEnum.Checked:
                    return CheckEnum.Unchecked;

                case CheckEnum.Unchecked:
                    return CheckEnum.Checked;

                case CheckEnum.TSChecked:
                    return CheckEnum.TSUnchecked;

                case CheckEnum.TSUnchecked:
                    return CheckEnum.TSGrayed;

                case CheckEnum.TSGrayed:
                    return CheckEnum.TSChecked;
            }
            return CheckEnum.None;
        }

        internal CheckEnum GetNextCheckValue(int row, int col)
        {
            return this.GetNextCheckValue(this.GetCellCheck(row, col));
        }

        internal virtual Style GetStyleDisplay(int row, int col)
        {
            Style styleDisplay = this._grid.GetStyleDisplay(row, col);
            if (this._kbdHandler.IsSearching() && this.IsCellCursor(row, col))
            {
                return this._grid.GetStyle(CellStyleEnum.Search).SetParent(styleDisplay, false);
            }
            if (this.IsCellHighlighted(row, col))
            {
                return this._grid.GetStyle(CellStyleEnum.Highlight).SetParent(styleDisplay, false);
            }
            if (this.IsCellCursor(row, col) && this.Focused)
            {
                return this._grid.GetStyle(CellStyleEnum.Focus).SetParent(styleDisplay, false);
            }
            return styleDisplay;
        }

        internal bool HasCursor()
        {
            return this.SelHandler.HasCursor();
        }

        public HitTestInfo HitTest(int x, int y)
        {
            return this._mouseHandler.HitTest(x, y);
        }

        protected void InitView()
        {
            base.ScrollPosition = new Point(0, 0);
            this.SetScrollSize();
            base.Invalidate();
        }

        public virtual void Invalidate(CellRange rg)
        {
            if (this.Redraw)
            {
                Rectangle cellRectDisplay = this.GetCellRectDisplay(rg.r1, rg.c1);
                if (!rg.IsSingleCell)
                {
                    cellRectDisplay = Rectangle.Union(cellRectDisplay, this.GetCellRectDisplay(rg.r2, rg.c2));
                }
                base.Invalidate(cellRectDisplay);
            }
        }

        internal void Invalidate(Point pt)
        {
            this.Invalidate(new CellRange(this._grid, pt.Y, pt.X));
        }

        public void Invalidate(int row, int col)
        {
            this.Invalidate(new CellRange(this._grid, row, col));
        }

        public void Invalidate(int row1, int col1, int row2, int col2)
        {
            this.Invalidate(new CellRange(this._grid, row1, col1, row2, col2));
        }

        internal virtual bool IsCellCursor(int row, int col)
        {
            return this._grid.IsCellCursor(row, col);
        }

        internal virtual bool IsCellFixed(int row, int col)
        {
            return this._grid.IsCellFixed(row, col);
        }

        internal virtual bool IsCellHighlighted(int row, int col)
        {
            if (this._grid.IsCellFixed(row, col))
            {
                return false;
            }
            if (!this._grid.IsCellSelected(row, col))
            {
                return false;
            }
            if (this.HighLight == HighLightEnum.Never)
            {
                return false;
            }
            if ((this.HighLight == HighLightEnum.WithFocus) && !this.Focused)
            {
                return false;
            }
            if (this._grid.IsCellCursor(row, col))
            {
                if ((this._focusRect != FocusRectEnum.None) && this.Focused)
                {
                    return false;
                }
                if (this.Editor != null)
                {
                    return false;
                }
            }
            return true;
        }

        internal int Last(RowColCollection coll)
        {
            int num = coll.Count - 1;
            while ((num > coll.Fixed) && (coll[num].SizeDisplay == 0))
            {
                num--;
            }
            return num;
        }

        public void LoadGrid(string fileName, FileFormatEnum format)
        {
            GridSaveLoad.LoadGrid(this, fileName, format, false, Encoding.ASCII);
        }

        public void LoadGrid(string fileName, FileFormatEnum format, bool fixedCells)
        {
            GridSaveLoad.LoadGrid(this, fileName, format, fixedCells, Encoding.ASCII);
        }

        public void LoadGrid(string fileName, FileFormatEnum format, bool fixedCells, Encoding encoding)
        {
            GridSaveLoad.LoadGrid(this, fileName, format, fixedCells, encoding);
        }

        internal void MouseSort(int col)
        {
            if (this.Rows.Count > this.Rows.Fixed)
            {
                SortColEventArgs e = new SortColEventArgs(col, SortFlags.None);
                Column column = this.Cols[col];
                bool flag = (column != this._grid._mouseSortCol) || ((column.Sort & SortFlags.Descending) != SortFlags.None);
                e.Order = flag ? ((e.Order | SortFlags.Ascending) & ~SortFlags.Descending) : ((e.Order | SortFlags.Descending) & ~SortFlags.Ascending);
                if (this.BeforeSort != null)
                {
                    this.BeforeSort(this, e);
                    if (e.Cancel || (e.Order == SortFlags.None))
                    {
                        return;
                    }
                    if (e.Handled)
                    {
                        this._grid.ShowSortAt(e.Order, col);
                        return;
                    }
                }
                int @fixed = col;
                if (this.AllowSorting == AllowSortingEnum.MultiColumn)
                {
                    @fixed = this.Cols.Fixed;
                    for (int i = this.Cols.Fixed; i < col; i++)
                    {
                        if (this.Cols[i].Sort == SortFlags.None)
                        {
                            this.Cols[i].Sort = SortFlags.Ascending;
                        }
                    }
                }
                column.Sort = e.Order;
                if (this._grid.IsDataBound())
                {
                    this._grid._dataSource.Sort(SortFlags.UseColSort, @fixed, col);
                }
                else
                {
                    this.Sort(SortFlags.UseColSort, @fixed, col);
                }
                this.ShowCell(this.Row, -1);
                if (this.AfterSort != null)
                {
                    this.AfterSort(this, e);
                }
            }
        }

        internal virtual void MoveSelection(MoveCursorEnum move, bool extend)
        {
            CellRange range = this.SelHandler.GetRange();
            int row = extend ? range.r2 : range.r1;
            int col = extend ? range.c2 : range.c1;
            this.MoveSelection(move, extend, row, col);
        }

        internal virtual void MoveSelection(MoveCursorEnum move, bool extend, int row, int col)
        {
            int num;
            CellRange range;
            switch (move)
            {
                case MoveCursorEnum.CellPrev:
                    num = this.Previous(this.Cols, col);
                    if (num == col)
                    {
                        num = this.Previous(this.Rows, row);
                        if (num != row)
                        {
                            row = num;
                            col = this.Last(this.Cols);
                        }
                        break;
                    }
                    col = num;
                    break;

                case MoveCursorEnum.CellNext:
                    num = this.Next(this.Cols, col);
                    if (num == col)
                    {
                        num = this.Next(this.Rows, row);
                        if (num != row)
                        {
                            row = num;
                            col = this.First(this.Cols);
                        }
                        break;
                    }
                    col = num;
                    break;

                case MoveCursorEnum.CellUp:
                    row = this.Previous(this.Rows, row);
                    break;

                case MoveCursorEnum.CellDown:
                    row = this.Next(this.Rows, row);
                    break;

                case MoveCursorEnum.CellLeft:
                    num = this.Previous(this.Cols, col);
                    if (num != col)
                    {
                        col = num;
                        break;
                    }
                    row = this._grid._tree.HandleKey(row, MoveCursorEnum.CellLeft);
                    break;

                case MoveCursorEnum.CellRight:
                    num = this.Next(this.Cols, col);
                    if (num != col)
                    {
                        col = num;
                        break;
                    }
                    row = this._grid._tree.HandleKey(row, MoveCursorEnum.CellRight);
                    break;

                case MoveCursorEnum.PageUp:
                    row = this.PreviousPage(this.Rows, row, true);
                    break;

                case MoveCursorEnum.PageDown:
                    row = this.NextPage(this.Rows, row, true);
                    break;

                case MoveCursorEnum.PageLeft:
                    col = this.PreviousPage(this.Cols, col, false);
                    break;

                case MoveCursorEnum.PageRight:
                    col = this.NextPage(this.Cols, col, false);
                    break;

                case MoveCursorEnum.HomeUp:
                    row = this.First(this.Rows);
                    break;

                case MoveCursorEnum.EndDown:
                    row = this.Last(this.Rows);
                    break;

                case MoveCursorEnum.HomeLeft:
                    col = this.First(this.Cols);
                    break;

                case MoveCursorEnum.EndRight:
                    col = this.Last(this.Cols);
                    break;
            }
            if (extend)
            {
                range = this.SelHandler.GetRange();
                range.r2 = row;
                range.c2 = col;
            }
            else
            {
                range = new CellRange(this._grid, row, col);
            }
            this.SelHandler.Select(this, range, true);
        }

        internal int Next(RowColCollection coll, int item)
        {
            if (item >= -1)
            {
                for (int i = item + 1; i < coll.Count; i++)
                {
                    if (coll[i].SizeDisplay > 0)
                    {
                        return i;
                    }
                }
            }
            return item;
        }

        internal int NextPage(RowColCollection coll, int item, bool vertical)
        {
            if (item < -1)
            {
                return item;
            }
            Rectangle scrollRectangle = this.ScrollRectangle;
            int num = vertical ? scrollRectangle.Height : scrollRectangle.Width;
            int num2 = 0;
            int num3 = -1;
            for (int i = item; i < coll.Count; i++)
            {
                num2 += coll[i].SizeDisplay;
                if (num2 >= num)
                {
                    num3 = Math.Max(item, i - 1);
                    break;
                }
            }
            if (num3 < 0)
            {
                num3 = coll.Count - 1;
            }
            while ((coll[num3].SizeDisplay == 0) && (num3 > coll.Fixed))
            {
                num3--;
            }
            return num3;
        }

        protected internal virtual void OnAfterCollapse(int row)
        {
            if (this.AfterCollapse != null)
            {
                RowColEventArgs e = new RowColEventArgs(row, this._grid._tree.Column);
                this.AfterCollapse(this, e);
            }
        }

        protected internal virtual void OnAfterDragRowCol(DragRowColEventArgs e)
        {
            if ((e.Col > -1) && (this.AfterDragColumn != null))
            {
                this.AfterDragColumn(this, e);
            }
            if ((e.Row > -1) && (this.AfterDragRow != null))
            {
                this.AfterDragRow(this, e);
            }
        }

        protected internal virtual void OnAfterEdit(int row, int col)
        {
            if (this.AfterEdit != null)
            {
                this.AfterEdit(this, new RowColEventArgs(row, col));
            }
        }

        protected internal virtual void OnAfterFreezeRowCol(RowColEventArgs e)
        {
            if ((e.Col > -1) && (this.AfterFreezeColumn != null))
            {
                this.AfterFreezeColumn(this, e);
            }
            if ((e.Row > -1) && (this.AfterFreezeRow != null))
            {
                this.AfterFreezeRow(this, e);
            }
        }

        protected internal virtual void OnAfterResizeRowCol(RowColEventArgs e)
        {
            if ((e.Col > -1) && (this.AfterResizeColumn != null))
            {
                this.AfterResizeColumn(this, e);
            }
            if ((e.Row > -1) && (this.AfterResizeRow != null))
            {
                this.AfterResizeRow(this, e);
            }
        }

        protected internal virtual void OnAfterSelChange()
        {
            CellRange rgOld = this.SelHandler._oldRange;
            CellRange rgNew = this.SelHandler._newRange;
            bool flag = (rgOld.r1 != rgNew.r1) || (rgOld.c1 != rgNew.c1);
            bool flag2 = (rgOld.r2 != rgNew.r2) || (rgOld.c2 != rgNew.c2);
            RangeEventArgs e = null;
            if (flag2 || flag)
            {
                e = new RangeEventArgs(rgOld, rgNew);
            }
            if (flag)
            {
                if (this.EnterCell != null)
                {
                    this.EnterCell(this, EventArgs.Empty);
                }
                if (this.RowColChange != null)
                {
                    this.RowColChange(this, EventArgs.Empty);
                }
                if (this.AfterRowColChange != null)
                {
                    this.AfterRowColChange(this, e);
                }
            }
            if (flag2 || flag)
            {
                if (this.SelChange != null)
                {
                    this.SelChange(this, EventArgs.Empty);
                }
                if (this.AfterSelChange != null)
                {
                    this.AfterSelChange(this, e);
                }
            }
        }

        protected internal virtual void OnBeforeAutosizeRowCol(RowColEventArgs e)
        {
            if ((e.Col > -1) && (this.BeforeAutosizeColumn != null))
            {
                this.BeforeAutosizeColumn(this, e);
            }
            if ((e.Row > -1) && (this.BeforeAutosizeRow != null))
            {
                this.BeforeAutosizeRow(this, e);
            }
        }

        protected internal virtual void OnBeforeCollapse(int row)
        {
            if (this.BeforeCollapse != null)
            {
                RowColEventArgs e = new RowColEventArgs(row, this._grid._tree.Column);
                this.BeforeCollapse(this, e);
                this._grid._tree._cancel = e.Cancel;
            }
        }

        protected internal virtual void OnBeforeDragRowCol(DragRowColEventArgs e)
        {
            if ((e.Col > -1) && (this.BeforeDragColumn != null))
            {
                this.BeforeDragColumn(this, e);
            }
            if ((e.Row > -1) && (this.BeforeDragRow != null))
            {
                this.BeforeDragRow(this, e);
            }
        }

        protected internal virtual void OnBeforeFreezeRowCol(RowColEventArgs e)
        {
            if ((e.Col > -1) && (this.BeforeFreezeColumn != null))
            {
                this.BeforeFreezeColumn(this, e);
            }
            if ((e.Row > -1) && (this.BeforeFreezeRow != null))
            {
                this.BeforeFreezeRow(this, e);
            }
        }

        protected internal virtual void OnBeforeResizeRowCol(RowColEventArgs e)
        {
            if ((e.Col > -1) && (this.BeforeResizeColumn != null))
            {
                this.BeforeResizeColumn(this, e);
            }
            if ((e.Row > -1) && (this.BeforeResizeRow != null))
            {
                this.BeforeResizeRow(this, e);
            }
        }

        protected internal virtual void OnBeforeSelChange()
        {
            CellRange rgOld = this.SelHandler._oldRange;
            CellRange rgNew = this.SelHandler._newRange;
            bool flag = (rgOld.r1 != rgNew.r1) || (rgOld.c1 != rgNew.c1);
            bool flag2 = (rgOld.r2 != rgNew.r2) || (rgOld.c2 != rgNew.c2);
            RangeEventArgs e = null;
            if (flag2 || flag)
            {
                e = new RangeEventArgs(rgOld, rgNew);
            }
            this.SelHandler._selCancel = false;
            if (flag)
            {
                if (this.LeaveCell != null)
                {
                    this.LeaveCell(this, EventArgs.Empty);
                }
                if (this.BeforeRowColChange != null)
                {
                    this.BeforeRowColChange(this, e);
                    this.SelHandler._selCancel = e.Cancel;
                }
            }
            if (!this.SelHandler._selCancel && ((flag || flag2) && (this.BeforeSelChange != null)))
            {
                this.BeforeSelChange(this, e);
                this.SelHandler._selCancel = e.Cancel;
            }
        }

        protected override void OnBindingContextChanged(EventArgs e)
        {
            if (!this._refreshing)
            {
                this._refreshing = true;
                this._grid._dataSource.RefreshData(this, true);
                this._refreshing = false;
            }
        }

        protected internal virtual void OnCellButtonClick(int row, int col)
        {
            if (this.CellButtonClick != null)
            {
                this.CellButtonClick(this, new RowColEventArgs(row, col));
            }
        }

        protected internal virtual void OnCellChanged(int row, int col)
        {
            if (this.CellChanged != null)
            {
                this.CellChanged(this, new RowColEventArgs(row, col));
            }
        }

        protected internal virtual void OnChangeEdit()
        {
            if (this.ChangeEdit != null)
            {
                this.ChangeEdit(this, EventArgs.Empty);
            }
        }

        protected internal virtual void OnComboCloseUp(int row, int col)
        {
            if (this.ComboCloseUp != null)
            {
                this.ComboCloseUp(this, new RowColEventArgs(row, col));
            }
        }

        protected internal virtual void OnComboDropDown(int row, int col)
        {
            if (this.ComboDropDown != null)
            {
                this.ComboDropDown(this, new RowColEventArgs(row, col));
            }
        }

        protected internal virtual void OnDataRefresh(ListChangedEventArgs e)
        {
            if (this.AfterDataRefresh != null)
            {
                this.AfterDataRefresh(this, e);
            }
        }

        private void OnFontChanged()
        {
            if (this._grid != null)
            {
                CellStyle normal = this.Styles.Normal;
                normal.Font = base.Font;
                Graphics graphics = base.CreateGraphics();
                int height = (int) graphics.MeasureString("Hj", normal.Font).Height;
                graphics.Dispose();
                int num2 = normal.Margins.Top + normal.Margins.Bottom;
                this.Rows.DefaultSize = (height + num2) + 3;
                this.Cols.DefaultSize = 5 * this.Rows.DefaultSize;
                this.SetScrollSize();
            }
        }

        protected override void OnGotFocus(EventArgs e)
        {
            if (this.HighLight == HighLightEnum.WithFocus)
            {
                base.Invalidate();
            }
            else
            {
                this.Invalidate(this.SelHandler.GetCursor());
            }
            base.OnGotFocus(e);
        }

        internal virtual void OnGridChanged(object sender, GridChangedEventArgs e)
        {
            switch (e.GridChangedType)
            {
                case GridChangedTypeEnum.RepaintGrid:
                    if (this.Redraw)
                    {
                        base.Invalidate();
                    }
                    goto Label_0259;

                case GridChangedTypeEnum.RepaintCell:
                    this.OnCellChanged(e.r1, e.c1);
                    break;

                case GridChangedTypeEnum.RepaintRange:
                    break;

                case GridChangedTypeEnum.BeforeCollapse:
                    this.OnBeforeCollapse(e.r1);
                    goto Label_0259;

                case GridChangedTypeEnum.AfterCollapse:
                    this.OnAfterCollapse(e.r1);
                    goto Label_0245;

                case GridChangedTypeEnum.EnsureVisible:
                    this.ShowCell(e.r1, e.c1);
                    goto Label_0259;

                case GridChangedTypeEnum.Select:
                    this.Select(e.r1, e.c1);
                    goto Label_0259;

                case GridChangedTypeEnum.RowMoved:
                case GridChangedTypeEnum.RowAdded:
                    if (!this._grid.IsDataBound())
                    {
                        this.ShowSortAt(SortFlags.None, -1);
                    }
                    else
                    {
                        this._grid._dataSource.UpdateSortGlyph();
                    }
                    goto Label_0245;

                case GridChangedTypeEnum.RowSelected:
                    if ((this.Redraw && (e.r1 <= this.BottomRow)) && (e.r2 >= this.TopRow))
                    {
                        this.Invalidate(e.r1, this.Cols.Fixed, e.r2, this.RightCol);
                    }
                    goto Label_0259;

                case GridChangedTypeEnum.ColSelected:
                    if ((this.Redraw && (e.c1 <= this.RightCol)) && (e.c2 >= this.LeftCol))
                    {
                        this.Invalidate(this.Rows.Fixed, e.c1, this.BottomRow, e.c2);
                    }
                    goto Label_0259;

                case GridChangedTypeEnum.BeforeSelChange:
                    this.OnBeforeSelChange();
                    goto Label_0259;

                case GridChangedTypeEnum.AfterSelChange:
                    this.OnAfterSelChange();
                    goto Label_0259;

                default:
                    goto Label_0245;
            }
            if (base.Visible && this.Redraw)
            {
                if (e.c1 < 0)
                {
                    this.Invalidate(e.r1, 0, e.r2, this.Cols.Count - 1);
                }
                else
                {
                    this.Invalidate(e.r1, e.c1, e.r2, e.c2);
                    if (this._showCursor && (this.Cols.Fixed > 0))
                    {
                        this.Invalidate(e.r1, 0, e.r2, 0);
                    }
                }
            }
            goto Label_0259;
        Label_0245:
            if (this.Redraw)
            {
                this.SetScrollSize();
                base.Invalidate();
            }
        Label_0259:
            if (this.GridChanged != null)
            {
                this.GridChanged(this, e);
            }
        }

        protected internal virtual void OnGridError(int row, int col, Exception exception, bool handled)
        {
            if (this.GridError != null)
            {
                GridErrorEventArgs e = new GridErrorEventArgs(row, col, exception, handled);
                this.GridError(this, e);
                handled = e.Handled;
            }
            if (!handled)
            {
                throw exception;
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            this._control = e.Control;
            this._shift = e.Shift;
            base.OnKeyDown(e);
            if (!e.Handled)
            {
                this._mouseHandler.CancelDragResize();
                if (this._kbdHandler.OnKeyDown(e))
                {
                    base.Update();
                }
            }
        }

        protected internal virtual bool OnKeyDownEdit(int row, int col, KeyEventArgs e)
        {
            if (this.KeyDownEdit == null)
            {
                return false;
            }
            KeyEditEventArgs args = new KeyEditEventArgs(row, col, e);
            this.KeyDownEdit(this, args);
            return args.Handled;
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);
            if (!e.Handled)
            {
                this._kbdHandler.OnKeyPress(e);
            }
        }

        protected internal virtual bool OnKeyPressEdit(int row, int col, KeyPressEventArgs e)
        {
            if (this.KeyPressEdit == null)
            {
                return false;
            }
            KeyPressEditEventArgs args = new KeyPressEditEventArgs(row, col, e);
            this.KeyPressEdit(this, args);
            return args.Handled;
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            this._control = e.Control;
            this._shift = e.Shift;
            base.OnKeyUp(e);
            bool handled = e.Handled;
        }

        protected internal virtual bool OnKeyUpEdit(int row, int col, KeyEventArgs e)
        {
            if (this.KeyUpEdit == null)
            {
                return false;
            }
            KeyEditEventArgs args = new KeyEditEventArgs(row, col, e);
            this.KeyUpEdit(this, args);
            return args.Handled;
        }

        protected override void OnLostFocus(EventArgs e)
        {
            this._mouseHandler.ResetMouse();
            if ((this.Editor == null) || !this.Editor.Focused)
            {
                if (this.HighLight == HighLightEnum.WithFocus)
                {
                    base.Invalidate();
                }
                else
                {
                    this.Invalidate(this.SelHandler.GetCursor());
                }
                if (this._grid.IsDataBound())
                {
                    this._grid._dataSource.OnLostFocus();
                }
                base.OnLostFocus(e);
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            bool cancel = false;
            if (this.BeforeMouseDown != null)
            {
                BeforeMouseDownEventArgs args = new BeforeMouseDownEventArgs(e);
                this.BeforeMouseDown(this, args);
                cancel = args.Cancel;
            }
            if (cancel || !this.FinishEditing())
            {
                base.Capture = false;
            }
            else
            {
                if ((e.Button & MouseButtons.Left) != MouseButtons.None)
                {
                    if (!this.Focused)
                    {
                        base.Focus();
                    }
                    TimeSpan span = (TimeSpan) (DateTime.Now - this._lastClick);
                    if (span.TotalMilliseconds < C1.Util.SystemInformation.DoubleClickTime)
                    {
                        this._mouseHandler.HandleDown(e);
                        this._mouseHandler.HandleDoubleClick();
                        this._lastClick = DateTime.MinValue;
                    }
                    else
                    {
                        this._mouseHandler.HandleDown(e);
                        this._lastClick = DateTime.Now;
                    }
                }
                base.OnMouseDown(e);
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            this._mouseHandler.HandleMove(e);
            base.OnMouseMove(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            this._mouseHandler.HandleUp();
            base.OnMouseUp(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (this.Redraw)
            {
                base.DrawBorders(e);
                this.DrawGrid(e);
                base.OnPaint(e);
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);
            this._grid._designMode = base.DesignMode;
        }

        protected override void OnResize(EventArgs e)
        {
            this.UpdateViewRange();
            base.OnResize(e);
        }

        protected override void OnScroll(ScrollBars sb)
        {
            CellRange rgOld = this._viewRange;
            this.UpdateViewRange();
            CellRange rgNew = this._viewRange;
            Rectangle clientRectangle = base.ClientRectangle;
            if (sb == ScrollBars.Horizontal)
            {
                int num = this.ScrollRectangle.Left - 1;
                clientRectangle.X += num;
                clientRectangle.Width -= num;
            }
            else if (sb == ScrollBars.Vertical)
            {
                int num2 = this.ScrollRectangle.Top - 1;
                clientRectangle.Y += num2;
                clientRectangle.Height -= num2;
            }
            base.Invalidate(clientRectangle);
            if (!this._cancelScroll && ((this.BeforeScroll != null) || (this.AfterScroll != null)))
            {
                RangeEventArgs e = new RangeEventArgs(rgOld, rgNew);
                if (this.BeforeScroll != null)
                {
                    this.BeforeScroll(this, e);
                }
                if (e.Cancel)
                {
                    this._cancelScroll = true;
                    this.TopRow = rgOld.r1;
                    this.LeftCol = rgOld.c1;
                    this._cancelScroll = false;
                }
                else if (this.AfterScroll != null)
                {
                    this.AfterScroll(this, e);
                }
            }
        }

        protected override void OnScrollTip(int newValue)
        {
            if ((this.BeforeScrollTip != null) && (this.Rows.Count > this.Rows.Fixed))
            {
                int row = this.Rows.Fixed + this.Rows.Frozen;
                if (row < this.Rows.Count)
                {
                    int pos = ((this.Rows[row].Top + this.Rows[row].Bottom) / 2) + newValue;
                    row = this.Rows.GetItemAt(pos);
                    while ((row < (this.Rows.Count - 1)) && (this.Rows[row].HeightDisplay == 0))
                    {
                        row++;
                    }
                    this.BeforeScrollTip(this, new RowColEventArgs(row, this.LeftCol));
                }
            }
        }

        protected internal virtual void OnSetupEditor(int row, int col)
        {
            if (this.SetupEditor != null)
            {
                this.SetupEditor(this, new RowColEventArgs(row, col));
            }
        }

        protected internal virtual bool OnStartEdit(int row, int col)
        {
            if (this.StartEdit == null)
            {
                return false;
            }
            RowColEventArgs e = new RowColEventArgs(row, col);
            this.StartEdit(this, e);
            this.Invalidate(row, col);
            return e.Cancel;
        }

        internal bool OnValidateEdit(int row, int col)
        {
            return this.OnValidateEdit(row, col, true);
        }

        protected internal virtual bool OnValidateEdit(int row, int col, bool valid)
        {
            if (this.ValidateEdit == null)
            {
                return !valid;
            }
            CheckEnum nextCheckValue = this.GetNextCheckValue(row, col);
            ValidateEditEventArgs e = new ValidateEditEventArgs(row, col, nextCheckValue);
            e.Cancel = !valid;
            if (this._validating)
            {
                return true;
            }
            this._validating = true;
            this.ValidateEdit(this, e);
            this._validating = false;
            return e.Cancel;
        }

        internal int Previous(RowColCollection coll, int item)
        {
            for (int i = item - 1; i >= coll.Fixed; i--)
            {
                if (coll[i].SizeDisplay > 0)
                {
                    return i;
                }
            }
            return item;
        }

        internal int PreviousPage(RowColCollection coll, int item, bool vertical)
        {
            Rectangle scrollRectangle = this.ScrollRectangle;
            int num = vertical ? scrollRectangle.Height : scrollRectangle.Width;
            int num2 = 0;
            int @fixed = -1;
            for (int i = item; i >= coll.Fixed; i--)
            {
                num2 += coll[i].SizeDisplay;
                if (num2 >= num)
                {
                    @fixed = Math.Min(item, i + 1);
                    break;
                }
            }
            if (@fixed < 0)
            {
                @fixed = coll.Fixed;
            }
            while ((coll[@fixed].SizeDisplay == 0) && (@fixed < (coll.Count - 1)))
            {
                @fixed++;
            }
            return @fixed;
        }

        public void RemoveItem()
        {
            this.RemoveItem(this.Rows.Count - 1);
        }

        public void RemoveItem(int index)
        {
            this.Rows.Remove(index);
        }

        public void SaveGrid(string fileName, FileFormatEnum format)
        {
            GridSaveLoad.SaveGrid(this, fileName, format, false, Encoding.ASCII);
        }

        public void SaveGrid(string fileName, FileFormatEnum format, bool fixedCells)
        {
            GridSaveLoad.SaveGrid(this, fileName, format, fixedCells, Encoding.ASCII);
        }

        public void SaveGrid(string fileName, FileFormatEnum format, bool fixedCells, Encoding encoding)
        {
            GridSaveLoad.SaveGrid(this, fileName, format, fixedCells, encoding);
        }

        public void Select(CellRange rg)
        {
            this.Select(rg, true);
        }

        internal void Select(Point pt)
        {
            this.Select(pt, true);
        }

        public void Select(CellRange rg, bool show)
        {
            this.SelHandler.Select(this, rg, show);
        }

        internal void Select(Point pt, bool show)
        {
            this.Select(pt.Y, pt.X, show);
        }

        public void Select(int row, int col)
        {
            this.Select(row, col, true);
        }

        public void Select(int row, int col, bool show)
        {
            this.Select(row, col, row, col, show);
        }

        public void Select(int row, int col, int rowSel, int colSel)
        {
            this.Select(row, col, rowSel, colSel, true);
        }

        public void Select(int row, int col, int rowSel, int colSel, bool show)
        {
            this.Select(new CellRange(this._grid, row, col, rowSel, colSel), show);
        }

        internal void SelectList(int row, int col, bool select, RowCollection selRows)
        {
            this.SelHandler.SelectList(this, row, col, select, selRows);
        }

        public virtual void SetCellCheck(int row, int col, CheckEnum check)
        {
            this._grid.SetCellCheck(row, col, check);
        }

        public void SetCellImage(int row, int col, Image newImage)
        {
            this._grid.SetCellImage(row, col, newImage);
        }

        public void SetCellStyle(int row, int col, CellStyle newStyle)
        {
            Style style = (newStyle == null) ? null : newStyle._style;
            this._grid.SetCellStyle(row, col, style);
        }

        public virtual bool SetData(CellRange rg, object data)
        {
            return this.SetData(rg, data, true);
        }

        public virtual bool SetData(CellRange rg, object data, bool coerce)
        {
            bool flag = true;
            rg.Normalize();
            for (int i = rg.r1; i <= rg.r2; i++)
            {
                for (int j = rg.c1; j <= rg.c2; j++)
                {
                    if (!this.SetDataInternal(i, j, data, coerce))
                    {
                        flag = false;
                    }
                }
            }
            return flag;
        }

        public virtual bool SetData(int row, int col, object data)
        {
            return this.SetData(row, col, data, true);
        }

        public virtual bool SetData(int row, int col, object data, bool coerce)
        {
            return this.SetDataInternal(row, col, data, coerce);
        }

        public void SetDataBinding(object dataSource, string dataMember)
        {
            this._grid.SetDataBinding(this, dataSource, dataMember);
        }

        internal bool SetDataInternal(int row, int col, object data, bool coerce)
        {
            bool flag = this._grid.SetData(row, col, data, coerce);
            if (!flag)
            {
                Exception exception = new ArgumentException(string.Format("Cannot assign value '{0}' to column {1}.", data, col));
                this.OnGridError(row, col, exception, true);
            }
            return flag;
        }

        protected virtual void SetScrollSize()
        {
            if (this.Redraw)
            {
                Size size = new Size(0, 0);
                int count = this.Cols.Count;
                if (count > 0)
                {
                    size.Width = this.Cols[count - 1].Right;
                }
                count = this.Rows.Count;
                if (count > 0)
                {
                    size.Height = this.Rows[count - 1].Bottom;
                }
                base.ScrollSize = size;
                this.UpdateViewRange();
                base.ScrollBarVert.SmallChange = this.Rows.DefaultSize;
                base.ScrollBarHorz.SmallChange = this.Cols.DefaultSize / 2;
            }
        }

        public bool ShouldSerializeAllowDragging()
        {
            return (this._allowDragging != AllowDraggingEnum.Columns);
        }

        public bool ShouldSerializeAllowFreezing()
        {
            return (this._allowFreezing != AllowFreezingEnum.None);
        }

        public bool ShouldSerializeAllowResizing()
        {
            return (this._allowResizing != AllowResizingEnum.Columns);
        }

        public bool ShouldSerializeAllowSorting()
        {
            return (this.AllowSorting != AllowSortingEnum.SingleColumn);
        }

        public bool ShouldSerializeAutoSearch()
        {
            return (this.AutoSearch != AutoSearchEnum.None);
        }

        public bool ShouldSerializeCellButtonImage()
        {
            return (this.CellButtonImage != null);
        }

        public bool ShouldSerializeDataMember()
        {
            return (this.DataMember != string.Empty);
        }

        public bool ShouldSerializeDataSource()
        {
            return (this.DataSource != null);
        }

        public bool ShouldSerializeDrawMode()
        {
            return (this.DrawMode != DrawModeEnum.Normal);
        }

        public bool ShouldSerializeFocusRect()
        {
            return (this._focusRect != FocusRectEnum.Light);
        }

        public bool ShouldSerializeHighLight()
        {
            return (this._highLight != HighLightEnum.Always);
        }

        public bool ShouldSerializeKeyActionEnter()
        {
            return (this.KeyActionEnter != KeyActionEnum.MoveDown);
        }

        public bool ShouldSerializeKeyActionTab()
        {
            return (this.KeyActionTab != KeyActionEnum.None);
        }

        public bool ShouldSerializeSelectionMode()
        {
            return (this.SelectionMode != SelectionModeEnum.Default);
        }

        public bool ShouldSerializeShowButtons()
        {
            return (this.ShowButtons != ShowButtonsEnum.WithFocus);
        }

        public bool ShouldSerializeSubtotalPosition()
        {
            return (this.SubtotalPosition != SubtotalPositionEnum.AboveData);
        }

        public bool ShouldSerializeSupportInfo()
        {
            return false;
        }

        public virtual void ShowCell(int row, int col)
        {
            if (((col <= this._viewRange.c1) || (col >= this._viewRange.c2)) || ((row <= this._viewRange.r1) || (row >= this._viewRange.r2)))
            {
                Rectangle cellRectDisplay = this.GetCellRectDisplay(row, col);
                Rectangle rectangle2 = cellRectDisplay;
                Rectangle clientRectangle = base.ClientRectangle;
                int num = this.Cols.Fixed + this.Cols.Frozen;
                if (col >= num)
                {
                    int left = this.Cols[num].Left;
                    if (rectangle2.Right > clientRectangle.Right)
                    {
                        rectangle2.X -= rectangle2.Right - clientRectangle.Right;
                    }
                    if (rectangle2.X < left)
                    {
                        rectangle2.X = left;
                    }
                }
                int num3 = this.Rows.Fixed + this.Rows.Frozen;
                if (row >= num3)
                {
                    int top = this.Rows[num3].Top;
                    if (rectangle2.Bottom > clientRectangle.Bottom)
                    {
                        rectangle2.Y -= rectangle2.Bottom - clientRectangle.Bottom;
                    }
                    if (rectangle2.Y < top)
                    {
                        rectangle2.Y = top;
                    }
                }
                if ((rectangle2.X != cellRectDisplay.X) || (rectangle2.Y != cellRectDisplay.Y))
                {
                    Point scrollPosition = base.ScrollPosition;
                    scrollPosition.Offset(rectangle2.X - cellRectDisplay.X, rectangle2.Y - cellRectDisplay.Y);
                    base.ScrollPosition = scrollPosition;
                }
            }
        }

        public void ShowSortAt(SortFlags order, int col)
        {
            this._grid.ShowSortAt(order, col);
        }

        public virtual void Sort(IComparer compare)
        {
            this._grid.Sort(this.Rows.Fixed, this.Rows.Count - this.Rows.Fixed, compare);
            this.ShowSortAt(SortFlags.None, -1);
        }

        public virtual void Sort(SortFlags order, CellRange rg)
        {
            this._grid.Sort(order, rg);
            this.ShowSortAt(order, -1);
        }

        public virtual void Sort(SortFlags order, int col)
        {
            this.Sort(order, col, col);
            this.ShowSortAt(order, col);
        }

        public virtual void Sort(SortFlags order, int col1, int col2)
        {
            this.Sort(order, new CellRange(this._grid, this.Rows.Fixed, col1, this.Rows.Count - 1, col2));
            this.ShowSortAt(order, col1);
        }

        public virtual void Sort(int index, int count, IComparer compare)
        {
            this._grid.Sort(index, count, compare);
            this.ShowSortAt(SortFlags.None, -1);
        }

        public bool StartEditing()
        {
            return this.StartEditing(this.Row, this.Col);
        }

        public bool StartEditing(int row, int col)
        {
            return this.StartEditing(row, col, '\r');
        }

        public virtual bool StartEditing(int row, int col, char key)
        {
            return this.StartEditing(row, col, key, true);
        }

        internal virtual bool StartEditing(int row, int col, char key, bool force)
        {
            this.Select(row, col, true);
            return this.EditHandler.StartEditing(row, col, key, force);
        }

        internal virtual bool StartEditing(int row, int col, Point ptMouse, bool dblClick)
        {
            return this.EditHandler.StartEditing(row, col, ptMouse, dblClick);
        }

        public void Subtotal(AggregateEnum function)
        {
            this.Subtotal(function, -1, -1, -1, -1, null);
        }

        public void Subtotal(AggregateEnum function, int level, int groupOn, int totalOn)
        {
            int groupFrom = (groupOn >= this.Cols.Fixed) ? this.Cols.Fixed : 0;
            if (groupOn == -1)
            {
                groupFrom = -1;
            }
            this.Subtotal(function, level, groupFrom, groupOn, totalOn, null);
        }

        public void Subtotal(AggregateEnum function, int level, int groupOn, int totalOn, string caption)
        {
            int groupFrom = (groupOn >= this.Cols.Fixed) ? this.Cols.Fixed : 0;
            if (groupOn == -1)
            {
                groupFrom = -1;
            }
            this.Subtotal(function, level, groupFrom, groupOn, totalOn, caption);
        }

        public void Subtotal(AggregateEnum function, int level, int groupFrom, int groupTo, int totalOn, string caption)
        {
            this._grid.Subtotal(function, level, groupFrom, groupTo, totalOn, caption);
        }

        internal void ToggleCellCheck(int row, int col)
        {
            this.ToggleCellCheck(row, col, false);
        }

        internal virtual void ToggleCellCheck(int row, int col, bool extend)
        {
            CheckEnum nextCheckValue = this.GetNextCheckValue(row, col);
            if (nextCheckValue != CheckEnum.None)
            {
                if ((extend && (this.SelectionMode == SelectionModeEnum.ListBox)) && this.Rows[row].Selected)
                {
                    for (int i = this.Rows.Fixed; i < this.Rows.Count; i++)
                    {
                        if (this.Rows[i].Selected && (this.GetCellCheck(i, col) != CheckEnum.None))
                        {
                            this.SetCellCheck(i, col, nextCheckValue);
                        }
                    }
                }
                else
                {
                    CellRange selection = this.Selection;
                    if ((extend && (this.SelectionMode != SelectionModeEnum.ListBox)) && selection.Contains(row, col))
                    {
                        for (int j = selection.r1; j <= selection.r2; j++)
                        {
                            for (int k = selection.c1; k <= selection.c2; k++)
                            {
                                if (this.GetCellCheck(j, k) != CheckEnum.None)
                                {
                                    this.SetCellCheck(j, k, nextCheckValue);
                                }
                            }
                        }
                    }
                    else
                    {
                        this.SetCellCheck(row, col, nextCheckValue);
                    }
                }
            }
        }

        protected override void UpdateScrollbars()
        {
            base.UpdateScrollbars();
            if (base._vScrollBar.Visible)
            {
                int largeChange = base._vScrollBar.LargeChange;
                for (int i = 0; i < (this.Rows.Fixed + this.Rows.Frozen); i++)
                {
                    largeChange -= this.Rows[i].HeightDisplay;
                }
                base._vScrollBar.LargeChange = Math.Max(largeChange, base._vScrollBar.SmallChange);
            }
            if (base._hScrollBar.Visible)
            {
                int num3 = base._hScrollBar.LargeChange;
                for (int j = 0; j < (this.Cols.Fixed + this.Cols.Frozen); j++)
                {
                    num3 -= this.Cols[j].WidthDisplay;
                }
                base._hScrollBar.LargeChange = Math.Max(num3, base._hScrollBar.SmallChange);
            }
        }

        protected virtual void UpdateViewRange()
        {
            if (this.Redraw && (this._grid != null))
            {
                CellRange range = new CellRange(this._grid, -1, -1);
                int num = this.Rows.Fixed + this.Rows.Frozen;
                Rectangle scrollRectangle = this.ScrollRectangle;
                if (num < this.Rows.Count)
                {
                    int pos = this.Rows[num].Top - base.ScrollPosition.Y;
                    range.r1 = this.Rows.GetItemAt(pos);
                    range.r2 = this.Rows.GetItemAt(pos + scrollRectangle.Height);
                    if (range.r2 < 0)
                    {
                        range.r2 = this.Rows.Count - 1;
                    }
                    if (range.r2 < this.Rows.Fixed)
                    {
                        range.r1 = range.r2 = num;
                    }
                }
                int num3 = this.Cols.Fixed + this.Cols.Frozen;
                if (num3 < this.Cols.Count)
                {
                    int num4 = this.Cols[num3].Left - base.ScrollPosition.X;
                    range.c1 = this.Cols.GetItemAt(num4);
                    range.c2 = this.Cols.GetItemAt(num4 + scrollRectangle.Width);
                    if (range.c2 < 0)
                    {
                        range.c2 = this.Cols.Count - 1;
                    }
                    if (range.c2 < num3)
                    {
                        range.c1 = range.c2 = num3;
                    }
                }
                this._viewRange = range;
                if (this.EditHandler.IsActive())
                {
                    base.Update();
                    this.EditHandler.UpdatePosition();
                }
            }
        }

        public AllowDraggingEnum AllowDragging
        {
            get
            {
                return this._allowDragging;
            }
            set
            {
                this._allowDragging = value;
            }
        }

        public bool AllowEditing
        {
            get
            {
                return this._allowEditing;
            }
            set
            {
                this._allowEditing = value;
            }
        }

        [DefaultValue(0)]
        public AllowFreezingEnum AllowFreezing
        {
            get
            {
                return this._allowFreezing;
            }
            set
            {
                this._allowFreezing = value;
            }
        }

        public AllowResizingEnum AllowResizing
        {
            get
            {
                return this._allowResizing;
            }
            set
            {
                this._allowResizing = value;
            }
        }

        public AllowSortingEnum AllowSorting
        {
            get
            {
                return this._allowSorting;
            }
            set
            {
                this._allowSorting = value;
                base.Invalidate();
            }
        }

        [DefaultValue(true)]
        public bool AutoResize
        {
            get
            {
                return this._autoResize;
            }
            set
            {
                this._autoResize = value;
            }
        }

        public AutoSearchEnum AutoSearch
        {
            get
            {
                return this._kbdHandler.AutoSearch;
            }
            set
            {
                this._kbdHandler.AutoSearch = value;
            }
        }

        [DefaultValue((double) 1.0)]
        public double AutoSearchDelay
        {
            get
            {
                return this._kbdHandler.AutoSearchDelay;
            }
            set
            {
                this._kbdHandler.AutoSearchDelay = value;
            }
        }

        public override Color BackColor
        {
            get
            {
                if (this._grid != null)
                {
                    return this.Styles.Normal.BackColor;
                }
                return base.BackColor;
            }
            set
            {
                if (base.BackColor != value)
                {
                    base.BackColor = value;
                }
                if ((this._grid != null) && (base.BackColor != this.Styles.Normal.BackColor))
                {
                    this.Styles.Normal.BackColor = value;
                    this.Styles.Alternate.BackColor = value;
                    base.Invalidate();
                }
            }
        }

        public int BottomRow
        {
            get
            {
                return this._viewRange.r2;
            }
        }

        public virtual Image CellButtonImage
        {
            get
            {
                return this._grid.ButtonImage;
            }
            set
            {
                this._grid.ButtonImage = value;
            }
        }

        public string Clip
        {
            get
            {
                if (this.SelectionMode != SelectionModeEnum.ListBox)
                {
                    return this._grid.GetClipRange(this.SelHandler.GetRange(), false);
                }
                return this._grid.GetClipSelRows(false);
            }
            set
            {
                this._grid.SetClipRange(this.SelHandler.GetRange(), value, false);
            }
        }

        public string ClipSeparators
        {
            get
            {
                return this._grid._clipSeparators;
            }
            set
            {
                if (((value == null) || (value.Length != 2)) || (value[0] == value[1]))
                {
                    throw new ArgumentException("ClipSeparators must be a string with two distinct characters.");
                }
                this._grid._clipSeparators = value;
            }
        }

        public int Col
        {
            get
            {
                return this.SelHandler._range.c1;
            }
            set
            {
                this.Select(this.Row, value);
            }
        }

        public ColumnCollection Cols
        {
            get
            {
                return this._grid._cols;
            }
        }

        public int ColSel
        {
            get
            {
                return this.SelHandler._range.c2;
            }
            set
            {
                this.ExtendSelection(this.RowSel, value, false);
            }
        }

        public string ComboList
        {
            get
            {
                return this._grid._comboList;
            }
            set
            {
                this._grid._comboList = ((value != null) && (value.Length > 0)) ? value : null;
            }
        }

        public virtual CellRange CursorCell
        {
            get
            {
                CellRange range = this.SelHandler.GetRange();
                range.r2 = range.r1;
                range.c2 = range.c1;
                return range;
            }
        }

        public string DataMember
        {
            get
            {
                return this._grid.GetDataMember();
            }
            set
            {
                this._grid.SetDataMember(this, value);
            }
        }

        public object DataSource
        {
            get
            {
                return this._grid.GetDataSource();
            }
            set
            {
                if ((value is C1FlexGridBase) || (value is GridModel))
                {
                    GridModel model = (value is C1FlexGridBase) ? ((C1FlexGridBase) value)._grid : ((GridModel) value);
                    if (model != this._grid)
                    {
                        if (model == null)
                        {
                            model = new GridModel(50, 10, 1, 1);
                        }
                        if (this._grid != null)
                        {
                            this._grid.OnGridChanged -= new GridChangedEventHandler(this.OnGridChanged);
                        }
                        this._grid = model;
                        if (this._grid != null)
                        {
                            this._grid.OnGridChanged += new GridChangedEventHandler(this.OnGridChanged);
                        }
                        this.SetScrollSize();
                    }
                }
                else
                {
                    this._grid.SetDataSource(this, value);
                }
            }
        }

        public DrawModeEnum DrawMode
        {
            get
            {
                return this._drawMode;
            }
            set
            {
                if (this._drawMode != value)
                {
                    this._drawMode = value;
                    base.Invalidate();
                }
            }
        }

        internal GridEditHandler EditHandler
        {
            get
            {
                return this._editHandler;
            }
        }

        public string EditMask
        {
            get
            {
                return this._grid._editMask;
            }
            set
            {
                this._grid._editMask = ((value != null) && (value.Length > 0)) ? value : null;
            }
        }

        public Control Editor
        {
            get
            {
                return (Control) this.EditHandler._editor;
            }
        }

        [DefaultValue(false)]
        public bool ExtendLastCol
        {
            get
            {
                return this._extendLastCol;
            }
            set
            {
                if (this._extendLastCol != value)
                {
                    this._extendLastCol = value;
                    base.Invalidate();
                }
            }
        }

        public FocusRectEnum FocusRect
        {
            get
            {
                return this._focusRect;
            }
            set
            {
                if (this._focusRect != value)
                {
                    this._focusRect = value;
                    this.Invalidate(this.SelHandler.GetCursor());
                }
            }
        }

        public override System.Drawing.Font Font
        {
            get
            {
                if (this._grid != null)
                {
                    return this.Styles.Normal.Font;
                }
                return base.Font;
            }
            set
            {
                if (base.Font != value)
                {
                    base.Font = value;
                    this.OnFontChanged();
                }
            }
        }

        public override Color ForeColor
        {
            get
            {
                if (this._grid != null)
                {
                    return this.Styles.Normal.ForeColor;
                }
                return base.ForeColor;
            }
            set
            {
                if (base.ForeColor != value)
                {
                    base.ForeColor = value;
                }
                if ((this._grid != null) && (base.ForeColor != this.Styles.Normal.ForeColor))
                {
                    this.Styles.Normal.ForeColor = value;
                    this.Styles.Alternate.ForeColor = value;
                    base.Invalidate();
                }
            }
        }

        public HighLightEnum HighLight
        {
            get
            {
                return this._highLight;
            }
            set
            {
                if (this._highLight != value)
                {
                    this._highLight = value;
                    base.Invalidate();
                }
            }
        }

        public object this[int row, int col]
        {
            get
            {
                return this.GetData(row, col);
            }
            set
            {
                this.SetData(row, col, value);
            }
        }

        public object this[int row, string colName]
        {
            get
            {
                return this.GetData(row, this.Cols[colName].Index);
            }
            set
            {
                this.SetData(row, this.Cols[colName].Index, value);
            }
        }

        public KeyActionEnum KeyActionEnter
        {
            get
            {
                return this._kbdHandler._actionEnter;
            }
            set
            {
                this._kbdHandler._actionEnter = value;
            }
        }

        public KeyActionEnum KeyActionTab
        {
            get
            {
                return this._kbdHandler._actionTab;
            }
            set
            {
                this._kbdHandler._actionTab = value;
            }
        }

        public int LeftCol
        {
            get
            {
                return this._viewRange.c1;
            }
            set
            {
                int num = this.Cols.Fixed + this.Cols.Frozen;
                if (value < num)
                {
                    value = num;
                }
                if (value >= this.Cols.Count)
                {
                    value = this.Cols.Count - 1;
                }
                if (value >= num)
                {
                    int num2 = this.Cols[value].Left - this.Cols[num].Left;
                    int num3 = (base.ScrollBarHorz.Maximum - base.ClientRectangle.Width) + 1;
                    if (num2 > num3)
                    {
                        num2 = num3;
                    }
                    base.ScrollPosition = new Point(-num2, base.ScrollPosition.Y);
                }
            }
        }

        public ProviderInfo LicensingInformation
        {
            get
            {
                return this._licProvider;
            }
        }

        public virtual int MouseCol
        {
            get
            {
                Point point = base.PointToClient(Control.MousePosition);
                point = this.GetCellAt(point.X, point.Y, true);
                if (point.X >= 0)
                {
                    return point.X;
                }
                return -1;
            }
        }

        public virtual int MouseRow
        {
            get
            {
                Point point = base.PointToClient(Control.MousePosition);
                point = this.GetCellAt(point.X, point.Y, true);
                if (point.Y >= 0)
                {
                    return point.Y;
                }
                return -1;
            }
        }

        public bool Redraw
        {
            get
            {
                if (this._grid == null)
                {
                    return false;
                }
                return this._grid.Redraw;
            }
            set
            {
                if (this._grid != null)
                {
                    this._grid.Redraw = value;
                }
            }
        }

        public int RightCol
        {
            get
            {
                return this._viewRange.c2;
            }
        }

        public int Row
        {
            get
            {
                return this.SelHandler._range.r1;
            }
            set
            {
                this.Select(value, this.Col);
            }
        }

        public RowCollection Rows
        {
            get
            {
                return this._grid._rows;
            }
        }

        public int RowSel
        {
            get
            {
                return this.SelHandler._range.r2;
            }
            set
            {
                this.ExtendSelection(value, this.ColSel, false);
            }
        }

        internal virtual Rectangle ScrollRectangle
        {
            get
            {
                Rectangle clientRectangle = base.ClientRectangle;
                RowColCollection rows = this.Cols;
                int num = rows.Fixed + rows.Frozen;
                if (num > 0)
                {
                    clientRectangle.X = rows[num - 1].End;
                    clientRectangle.Width -= clientRectangle.X;
                }
                rows = this.Rows;
                num = rows.Fixed + rows.Frozen;
                if (num > 0)
                {
                    clientRectangle.Y = rows[num - 1].End;
                    clientRectangle.Height -= clientRectangle.Y;
                }
                return clientRectangle;
            }
        }

        public virtual CellRange Selection
        {
            get
            {
                CellRange range = this.SelHandler.GetRange();
                range.Normalize();
                return range;
            }
        }

        public SelectionModeEnum SelectionMode
        {
            get
            {
                return this.SelHandler.SelectionMode;
            }
            set
            {
                this.SelHandler.SelectionMode = value;
            }
        }

        internal GridSelHandler SelHandler
        {
            get
            {
                return this._grid._selHandler;
            }
        }

        public ShowButtonsEnum ShowButtons
        {
            get
            {
                return this._showButtons;
            }
            set
            {
                this._showButtons = value;
                base.Invalidate();
            }
        }

        [DefaultValue(false)]
        public bool ShowCursor
        {
            get
            {
                return this._showCursor;
            }
            set
            {
                this._showCursor = value;
                base.Invalidate();
            }
        }

        [DefaultValue(true)]
        public bool ShowSort
        {
            get
            {
                return this._showSort;
            }
            set
            {
                this._showSort = value;
                base.Invalidate();
            }
        }

        public string StyleInfo
        {
            get
            {
                return this.Styles.BuildString(false);
            }
            set
            {
                this.Styles.ParseString(value);
            }
        }

        public CellStyleCollection Styles
        {
            get
            {
                return this._grid._styles;
            }
        }

        public SubtotalPositionEnum SubtotalPosition
        {
            get
            {
                return this._grid.SubtotalPosition;
            }
            set
            {
                this._grid.SubtotalPosition = value;
            }
        }

        public string SupportInfo
        {
            get
            {
                return string.Empty;
            }
            set
            {
            }
        }

        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                base.Text = value;
            }
        }

        public int TopRow
        {
            get
            {
                return this._viewRange.r1;
            }
            set
            {
                int num = this.Rows.Fixed + this.Rows.Frozen;
                if (value < num)
                {
                    value = num;
                }
                if (value >= this.Rows.Count)
                {
                    value = this.Rows.Count - 1;
                }
                if (value >= num)
                {
                    int num2 = this.Rows[value].Top - this.Rows[num].Top;
                    int num3 = (base.ScrollBarVert.Maximum - base.ClientRectangle.Height) + 1;
                    if (num2 > num3)
                    {
                        num2 = num3;
                    }
                    base.ScrollPosition = new Point(base.ScrollPosition.X, -num2);
                }
            }
        }

        public GridTree Tree
        {
            get
            {
                return this._grid._tree;
            }
        }
    }
}

